import javafx.scene.layout.Priority;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

public class No040 {
    /**
     * 输入n个整数，找出其中最小的K个数。
     * 例如输入4,5,1,6,2,7,3,8这8个数字，则最小的4个数字是1,2,3,4,。
     */
    /*
    基于Partition的方法 ：时间复杂度O(n)       需要修改输入数组     不适用于海量数据
    基于堆或红黑树的方法 ：时间复杂度O(nlogk)   不需要修改输入数组   适用于海量数据
     */
    // Partition
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> result = new ArrayList<>();
        if (input == null || input.length == 0 || input.length < k || k == 0) {
            return result;
        }
        // 在数组中寻找位置为k - 1的pivot
        int start = 0, end = input.length - 1;
        int index = SortQuick.Partition(input, start, end);
        while (index != k - 1) {
            if (index < k - 1) {
                start = index + 1;
            } else {
                end = index - 1;
            }
            index = SortQuick.Partition(input, start, end);
        }

        // 收集这k个数
        for (int i = 0; i <= index; i++) {
            result.add(input[i]);
        }
        return result;
    }


    //堆
    public ArrayList<Integer> GetLeastNumbers_Solution2(int[] input, int k) {
        ArrayList<Integer> result = new ArrayList<>();
        if (input == null || input.length == 0 || input.length < k || k == 0) {
            return result;
        }
        // 构建大根堆,自然顺序naturalOrder 逆序reverseOrder
        PriorityQueue<Integer> bigHeap = new PriorityQueue<>(Comparator.reverseOrder());
        for (int i = 0; i < input.length; i++) {
            if (bigHeap.size() < k) {
                bigHeap.add(input[i]);
            } else if (!bigHeap.isEmpty() && input[i] < bigHeap.peek()) {
                bigHeap.poll();
                bigHeap.add(input[i]);
            }
        }

        while (!bigHeap.isEmpty()) {
            result.add(bigHeap.poll());
        }
        return result;
    }

}
